Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

75장. SNS — 팬아웃 패턴

이 장에서 말하고자 하는 것

SQS는 한 큐에 한 Consumer 그룹이 붙는 구조다.

한 메시지 → 한 그룹이 처리

그런데 같은 메시지를 여러 곳에 동시에 보내야 할 때가 있다.

"주문 생성됨"
  → 알림 서비스도 알아야 하고
  → 분석 서비스도 알아야 하고
  → 추천 서비스도 알아야 하고
  → 재고 서비스도 알아야 한다

이때 등장하는 게

Amazon SNS (Simple Notification Service)

다.


1. SNS의 기본 모델 — 1:N

[Publisher]
   ↓ Publish
[Topic: order-events]
   ↓ 동일 메시지를 모든 구독자에게 전달
   ├─ Subscriber 1 (SQS)
   ├─ Subscriber 2 (SQS)
   ├─ Subscriber 3 (Lambda)
   └─ Subscriber 4 (HTTPS endpoint)
  • 토픽에 한 번 발행하면 모든 구독자에게 복제 전달
  • Publisher는 누가 받는지 모른다
  • 구독자는 자유롭게 추가/삭제

2. Fan-out 패턴 — SNS + SQS 조합

가장 흔한 운영 패턴이다.

[Publisher]
   ↓
[SNS Topic]
   ├─ SQS: notification-jobs    → notification worker
   ├─ SQS: analytics-jobs        → analytics worker
   ├─ SQS: recommendation-jobs   → recommendation worker
   └─ SQS: inventory-jobs        → inventory worker
  • 발행자는 SNS에 한 번
  • 각 Worker는 자기 큐에서 자기 페이스로 처리
  • 한쪽이 막혀도 다른 큐에는 영향 없음
  • 새 구독자를 추가해도 발행자 코드는 변경 없음

SNS 직접 → Lambda / HTTPS 도 가능하지만 SNS → SQS → Worker가 안정적


3. 메시지 필터링 — 받고 싶은 것만 받기

SNS는 구독에 필터 정책 을 둘 수 있다.

구독자가 받고 싶은 것:
  { "type": ["OrderCreated", "OrderCancelled"] }

토픽에 흘러오는 메시지:
  - OrderCreated   → 통과
  - OrderShipped   → 차단
  - OrderCancelled → 통과

필터링은 SNS 단계에서 일어나므로 불필요한 트래픽이 SQS까지 가지 않는다.


4. Order는 보장하지 않는다 (기본)

SNS Standard 토픽은 순서 보장이 없다.

"OrderCreated" → "OrderPaid" 발행
  ↓
구독자는 "OrderPaid" 가 먼저 도착할 수도 있다

순서가 중요한 도메인은 SNS FIFO + SQS FIFO 조합으로 묶는다.


5. SNS와 EventBridge — 비슷한데 다르다

“둘 다 1:N 인데 뭐가 다른가?”

이 질문이 자주 나온다.

SNS         → 단순 팬아웃 (빠름, 저비용)
EventBridge → 풍부한 라우팅, 서드파티 통합, 스키마 레지스트리
  • 내부 단순 fan-out → SNS
  • 복잡한 라우팅 / 서드파티 SaaS · AWS 서비스 이벤트 통합 → EventBridge

다음 76장에서 자세히 본다.


6. 우리 서비스에서

[orders 서비스]
   ↓ Publish "OrderCreated"
[SNS Topic: order-events]
   ├─ SQS: notification-jobs    → ECS notification worker → 이메일/푸시
   ├─ SQS: analytics-jobs        → ECS analytics worker  → DynamoDB
   └─ SQS: inventory-jobs        → ECS inventory worker  → 재고 차감
  • orders 서비스 코드는 단 한 줄: sns.publish(...)
  • 새 도메인(예: loyalty) 이 생기면 그쪽 SQS를 토픽에 구독시키면 끝

7. 직접 확인해보기 — CLI

토픽 만들기

aws sns create-topic --name order-events

구독 (SQS)

aws sns subscribe \
  --topic-arn <topic-arn> \
  --protocol sqs \
  --notification-endpoint <sqs-queue-arn>

발행

aws sns publish \
  --topic-arn <topic-arn> \
  --message '{"type":"OrderCreated","orderId":"o-1"}' \
  --message-attributes '{
    "type": {"DataType":"String","StringValue":"OrderCreated"}
  }'

message-attributes 가 필터 정책의 기준이 된다.


8. 코드로는 이렇게 생겼다 — Terraform

resource "aws_sns_topic" "order_events" {
  name = "order-events"
}

resource "aws_sqs_queue" "notification_jobs" {
  name = "notification-jobs"
}

resource "aws_sns_topic_subscription" "notification" {
  topic_arn            = aws_sns_topic.order_events.arn
  protocol             = "sqs"
  endpoint             = aws_sqs_queue.notification_jobs.arn
  raw_message_delivery = true

  filter_policy = jsonencode({
    type = ["OrderCreated", "OrderCancelled"]
  })
}

# SNS가 SQS에 쓸 수 있도록 큐 정책
resource "aws_sqs_queue_policy" "notification" {
  queue_url = aws_sqs_queue.notification_jobs.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "sns.amazonaws.com" }
      Action    = "sqs:SendMessage"
      Resource  = aws_sqs_queue.notification_jobs.arn
      Condition = {
        ArnEquals = { "aws:SourceArn" = aws_sns_topic.order_events.arn }
      }
    }]
  })
}

SNS → SQS의 권한 설정이 자주 까먹는 부분이다.


9. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. SNS → 여러 Lambda 직접 구독

Lambda 가 한 번이라도 실패하면 메시지 손실 가능 (재시도는 있지만 한계).

안정성이 중요하면 SNS → SQS → Lambda

안티패턴 2. 한 큐에 여러 도메인 메시지를 섞는다

필터 없이 모든 메시지가 한 큐에 → 워커가 자기와 무관한 메시지까지 처리.

도메인별 큐를 분리하고 SNS 필터로 분기

안티패턴 3. 메시지 본문에 거대한 페이로드를 넣는다

SNS · SQS는 메시지 크기 제한이 있다 (기본 256KB).
큰 데이터는 S3에 두고 SNS에는 키만.

안티패턴 4. 발행자가 누가 받는지 신경 쓴다

SNS의 핵심은 발행자/구독자 분리.
발행자가 구독자 추가/제거를 알아야 한다면 추상화가 무너진 것.


10. 한 줄로 정리

SNS는 1:N 팬아웃 도구이며,
“SNS → 여러 SQS → 각자 워커” 가 가장 안정적인 패턴이다


11. 이 장의 핵심 정리

  1. SNS는 토픽 기반의 1:N 발행/구독 모델이다.
  2. 발행자는 구독자를 모른다 — 결합도가 결정적으로 낮아진다.
  3. SNS → SQS → Worker 가 가장 안정적인 운영 패턴이다.
  4. 필터 정책으로 구독자가 받고 싶은 것만 받는다.
  5. 순서가 중요하면 SNS FIFO + SQS FIFO.
  6. 단순 팬아웃은 SNS, 복잡한 라우팅은 EventBridge.